﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;
using System.Drawing;
using Microsoft.Win32;
using System.Windows.Media.Imaging;

namespace Hi_Baidu.Model.ProcessModel
{
    public class IOProcessModel : Model
    {
        /// <summary>
        ///     获取当前PC所有硬盘驱动器列表
        /// </summary>
        /// <returns>
        ///     返回硬盘驱动器列表
        /// </returns>
        public static DriveInfo[] GetDriveInfo()
        {
            return DriveInfo.GetDrives();
        }

        /// <summary>
        ///     获取路径的下一层目录列表
        /// </summary>
        /// <param name="Path" type="string">
        ///     <para>
        ///         路径
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回目录列表
        /// </returns>
        public static String[] GetDirectory(String Path)
        {
            return Directory.GetDirectories(Path);
        }

        /// <summary>
        ///     获取路径的下一层文件列表
        /// </summary>
        /// <param name="Path" type="string">
        ///     <para>
        ///         路径
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回文件列表
        /// </returns>
        public static String[] GetFiles(String Path)
        {
            return Directory.GetFiles(Path);
        }


        /// <summary>
        /// 依据文件名读取图标，若指定文件不存在，则返回空值。
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public static Icon GetIconByFileName(string fileName)
        {
            if (fileName == null || fileName.Equals(string.Empty)) return null;
            if (!File.Exists(fileName)) return null;

            SHFILEINFO shinfo = new SHFILEINFO();
            //Use this to get the small Icon
            Win32.SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), Win32.SHGFI_ICON | Win32.SHGFI_SMALLICON);
            //The icon is returned in the hIcon member of the shinfo struct
            System.Drawing.Icon myIcon = System.Drawing.Icon.FromHandle(shinfo.hIcon);
            return myIcon;
        }

        /// <summary>
        /// 给出文件扩展名（.*），返回相应图标
        /// 若不以"."开头则返回文件夹的图标。
        /// </summary>
        /// <param name="fileType"></param>
        /// <param name="isLarge"></param>
        /// <returns></returns>
        public static Icon GetIconByFileType(string fileType, bool isLarge)
        {
            if (fileType == null || fileType.Equals(string.Empty)) return null;

            RegistryKey regVersion = null;
            string regFileType = null;
            string regIconString = null;
            string systemDirectory = Environment.SystemDirectory + "\\";

            if (fileType[0] == '.')
            {
                //读系统注册表中文件类型信息
                regVersion = Registry.ClassesRoot.OpenSubKey(fileType, true);
                if (regVersion != null)
                {
                    regFileType = regVersion.GetValue("") as string;
                    regVersion.Close();
                    regVersion = Registry.ClassesRoot.OpenSubKey(regFileType + @"\DefaultIcon", true);
                    if (regVersion != null)
                    {
                        regIconString = regVersion.GetValue("") as string;
                        regVersion.Close();
                    }
                }
                if (regIconString == null)
                {
                    //没有读取到文件类型注册信息，指定为未知文件类型的图标
                    regIconString = systemDirectory + "shell32.dll,0";
                }
            }
            else
            {
                //直接指定为文件夹图标
                regIconString = systemDirectory + "shell32.dll,3";
            }
            string[] fileIcon = regIconString.Split(new char[] { ',' });
            if (fileIcon.Length != 2)
            {
                //系统注册表中注册的标图不能直接提取，则返回可执行文件的通用图标
                fileIcon = new string[] { systemDirectory + "shell32.dll", "2" };
            }
            Icon resultIcon = null;
            try
            {
                //调用API方法读取图标
                int[] phiconLarge = new int[1];
                int[] phiconSmall = new int[1];
                uint count = Win32.ExtractIconEx(fileIcon[0], Int32.Parse(fileIcon[1]), phiconLarge, phiconSmall, 1);
                IntPtr IconHnd = new IntPtr(isLarge ? phiconLarge[0] : phiconSmall[0]);
                resultIcon = Icon.FromHandle(IconHnd);
            }
            catch { }
            return resultIcon;

        }

        /// <summary>
        ///     将图标类型转换成WPF程序可认的BitmapImage
        /// </summary>
        /// <param name="ico" type="System.Drawing.Icon">
        ///     <para>
        ///         要转换的图标
        ///     </para>
        /// </param>
        /// <returns>
        ///     返回null , 标示转换失败
        /// </returns>
        public static BitmapImage ConvertToWPF(Icon ico)
        {
            if(ico != null)
            {
                MemoryStream Ms = new MemoryStream();
                ico.ToBitmap().Save(Ms, System.Drawing.Imaging.ImageFormat.Png);
                BitmapImage BImage = new BitmapImage();
                BImage.BeginInit();
                BImage.StreamSource = Ms;
                BImage.EndInit();
                return BImage;
            }
            else
            {
                return null;
            }
        }

    }

    [StructLayout(LayoutKind.Sequential)]
    public struct SHFILEINFO
    {
        public IntPtr hIcon;
        public IntPtr iIcon;
        public uint dwAttributes;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
        public string szDisplayName;
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
        public string szTypeName;
    };

    /// <summary>
    /// 定义调用的API方法
    /// </summary>
    class Win32
    {
        public const uint SHGFI_ICON = 0x100;
        public const uint SHGFI_LARGEICON = 0x0; // 'Large icon
        public const uint SHGFI_SMALLICON = 0x1; // 'Small icon

        [DllImport("shell32.dll")]
        public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
        [DllImport("shell32.dll")]
        public static extern uint ExtractIconEx(string lpszFile, int nIconIndex, int[] phiconLarge, int[] phiconSmall, uint nIcons);
    }
}
